package com.smedi.ismedi.inmail.core.application.query.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.smedi.ismedi.authority.starter.util.VerifyHelper;
import com.smedi.ismedi.inmail.core.application.command.LoginLogPageCommand;
import com.smedi.ismedi.inmail.core.application.convert.AppConverter;
import com.smedi.ismedi.inmail.core.application.query.LoginLogQueryService;
import com.smedi.ismedi.inmail.core.domain.aggregatemodel.LoginLog;
import com.smedi.ismedi.inmail.core.domain.aggregatemodel.OperationLog;
import com.smedi.ismedi.inmail.core.port.adapter.persistence.model.LoginLogEntity;
import com.smedi.ismedi.inmail.core.port.adapter.persistence.model.OperationLogEntity;
import com.smedi.ismedi.inmail.core.port.adapter.persistence.mybatis.mapper.LoginLogMapper;
import com.smedi.ismedi.inmail.core.port.adapter.persistence.mybatis.mapper.OperationLogMapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 查询服务实现类
 *
 * @author jiangqinxuan
 * @date 2021/07/30
 */
@Service
@AllArgsConstructor
@Slf4j
@SuppressWarnings("all" )
public class LoginLogQueryServiceImpl implements LoginLogQueryService {
    private final LoginLogMapper loginLogMapper;
    private final OperationLogMapper operationLogMapper;
    private final AppConverter appConverter;

    @Override
    public Page<LoginLog> page(LoginLogPageCommand loginLogPageCommand) {
        Page<LoginLogEntity> loginLogEntityPage = loginLogMapper.selectPage(new Page<>(loginLogPageCommand.getCurrent(), loginLogPageCommand.getSize()),
                new LambdaQueryWrapper<LoginLogEntity>()
                        .eq(VerifyHelper.isAvailable(loginLogPageCommand.getPersonId()), LoginLogEntity::getLoginUserId, loginLogPageCommand.getPersonId())
                        .lt(VerifyHelper.isAvailable(loginLogPageCommand.getLoginTimeLt()), LoginLogEntity::getLoginTime, loginLogPageCommand.getLoginTimeLt())
                        .orderBy(true, false, LoginLogEntity::getLoginTime));
        return this.expand(loginLogEntityPage);
    }

    private Page<LoginLog> expand(Page<LoginLogEntity> loginLogEntityPage) {
        Page<LoginLog> loginLogPage = appConverter.loginLogEntityToLoginLog(loginLogEntityPage);
        loginLogPage.setRecords(this.expand(loginLogEntityPage.getRecords()));
        return loginLogPage;
    }

    private List<LoginLog> expand(List<LoginLogEntity> loginLogEntities) {
        List<LoginLog> loginLogs = new ArrayList<>();
        if (VerifyHelper.isNotAvailable(loginLogEntities)) {
            return loginLogs;
        }
        Set<Long> loginLogIds = new HashSet<>();
        for (LoginLogEntity loginLog : loginLogEntities) {
            loginLogIds.add(loginLog.getId());
        }
        Map<Long, List<OperationLog>> loginLogIdOperationLogsMap = new HashMap<>();
        if (VerifyHelper.isAvailable(loginLogIds)) {
            List<OperationLogEntity> operationLogEntities = operationLogMapper.selectList(new LambdaQueryWrapper<OperationLogEntity>()
                    .in(OperationLogEntity::getLoginLogId, new ArrayList<>(loginLogIds)));
            for (OperationLogEntity operationLogEntity : operationLogEntities) {
                List<OperationLog> operationLogs = loginLogIdOperationLogsMap.getOrDefault(operationLogEntity.getLoginLogId(), new ArrayList<>());
                operationLogs.add(appConverter.operationLogEntityToOperationLog(operationLogEntity));
                loginLogIdOperationLogsMap.put(operationLogEntity.getLoginLogId(), operationLogs);
            }
        }
        for (LoginLogEntity loginLogEntity : loginLogEntities) {
            LoginLog loginLog = appConverter.loginLogEntityToLoginLog(loginLogEntity);
            loginLog.setOperationLogs(loginLogIdOperationLogsMap.get(loginLogEntity.getId()));
            loginLogs.add(loginLog);
        }
        return loginLogs;
    }
}
